package com.xd.common.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.db.ds.DSFactory;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.experimental.Accessors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.io.File;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.util.List;

@Configuration
public class ExportSQL {
    // 用于打印执行日志
    private static final Logger logger = LoggerFactory.getLogger(ExportSQL.class);

    // 存储的路径
    @Value("${sql.filePath}")
    private String filePath;

    // 数据库名
    @Value("${sql.dbname}")
    private String database_name;

    // 需要导出的表名
    private final List<TempBean> tempBeanList = CollectionUtil.newArrayList(
            // 这里写需要存储的表名 有几张表就new几个
            new TempBean().setTable("city_info")
    );

    @SneakyThrows
    public void export() {
        //获取默认数据源
        DataSource ds = DSFactory.get();
        // 获取数据库连接对象
        Connection connection = ds.getConnection();
        // 获取连接信息
        DatabaseMetaData metaData = connection.getMetaData();
        // 创建sql文件对象
        FileWriter sqlFileWriter = FileWriter.create(new File(filePath + database_name + ".sql"));
        sqlFileWriter.write("");
        sqlFileWriter.append("USE " + database_name + ";\n");
        sqlFileWriter.append("/*\n");
        sqlFileWriter.append(" --------------------------------------------------\n");
        sqlFileWriter.append(" Target Server Type    : " + metaData.getDatabaseProductName() + ";\n");
        sqlFileWriter.append(" Target Server Version : " + metaData.getDatabaseProductVersion() + ";\n");
        sqlFileWriter.append(" \n");
        sqlFileWriter.append(" Target Server Date : " + DateTime.now() + ";\n");
        sqlFileWriter.append(" \n");
        sqlFileWriter.append(" --------------------------------------------------\n");
        sqlFileWriter.append("*/\n");
        sqlFileWriter.append("SET NAMES utf8mb4;\n");
        sqlFileWriter.append("SET FOREIGN_KEY_CHECKS = 0;\n");
        for (TempBean tempBean : tempBeanList) {
            String table = tempBean.table;
            sqlFileWriter.append("\n\n\n");
            // DROP TABLE
            sqlFileWriter.append("DROP TABLE IF EXISTS `" + table + "`;\n");
            // CREATE TABLE
            Entity createTableEntity = Db.use().queryOne("SHOW CREATE TABLE " + table);
            sqlFileWriter.append((String) createTableEntity.get("Create Table"));
            sqlFileWriter.append(";\n");
            // 看配置，是否需要insert语句
            if (!tempBean.insert) {
                continue;
            }
            // INSERT INTO
            List<Entity> dataEntityList = Db.use().query("SELECT * FROM " + table);
            for (Entity dataEntity : dataEntityList) {
                StrBuilder field = StrBuilder.create();
                StrBuilder data = StrBuilder.create();

                dataEntity.forEach((key, value) -> {
                    field.append(key).append(", ");
                    if (ObjectUtil.isNotNull(value)) {
                        if (StrUtil.equals("true", String.valueOf(value))) {
                            data.append("b'1'");
                        } else if (StrUtil.equals("false", String.valueOf(value))) {
                            data.append("b'0'");
                        } else {
                            data.append("'").append(value).append("'");
                        }
                    } else {
                        data.append("NULL");
                    }
                    data.append(", ");
                });

                sqlFileWriter.append("INSERT INTO `" + table + "`(");
                String fieldStr = field.subString(0, field.length() - 2);
                sqlFileWriter.append(fieldStr);
                sqlFileWriter.append(") VALUES (");
                String dataStr = data.subString(0, data.length() - 2);
                sqlFileWriter.append(dataStr);
                sqlFileWriter.append(");\n");
            }
        }
        sqlFileWriter.append("\n\n\n");
        sqlFileWriter.append("SET FOREIGN_KEY_CHECKS = 1;\n");
        logger.info(">>>>>>>>>> 存储sql成功" + DateTime.now());
    }

    @Data
    @Accessors(chain = true)
    static class TempBean {
        // 表名
        public String table;
        // 是否需要insert语句，默认需要 (表中数据)
        public Boolean insert = true;
    }

}

